package cn.buk.tms.entity.misc;

import static java.util.regex.Pattern.compile;

import cn.buk.common.util.DateUtil;
import com.fasterxml.jackson.annotation.JsonFormat;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.persistence.Transient;
import jakarta.persistence.UniqueConstraint;

@Entity
@Table(name="t240",	uniqueConstraints=@UniqueConstraint(name="uk_t240_enterprise_id_pnrno",	columnNames={"enterprise_id", "pnrNo"} ))
public class Pnr {

  @Id
  @Column(name="pnrid")
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private int id;

  @Column(name = "enterprise_id", nullable = false)
  private int enterpriseId;

  @Column(name = "pnrNo", length = 7, nullable = false)
  private String pnrNo;


  /**
   * 大编码，和pnrno配合，确定是否为同一个编码
   */
  @Column(length = 7, name = "big_pnr")
  private String bigPnrNo;


  /**
   * 第一程或单程的出发机场
   */
  @Column(name = "dport", length = 3)
  private String dport;

  /**
   * 第一程或单程的到达机场
   */
  @Column(name = "aport", length = 3)
  private String aport;

  /**
   * 第一程或单程的航班号
   */
  @Column(name = "flight_no", length = 7)
  private String flightNo;

  /**
   * 第一程或单程的出发日期
   */
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  @Temporal(TemporalType.DATE)
  @Column(name = "ddate")
  private Date ddate;

  /**
   * 第一程或单程的出发时间
   */
  @Column(name = "dtime", length = 4)
  private String dtime;

  /**
   * 第一程或单程的预定的舱位
   */
  @Column(length = 2)
  private String subclass;


  @Column(name = "customer_id")
  private Integer customerId;

  /**
   * 预定该PNR的用户所使用的eterm用户名
   */
  @Column(name="eterm_username", length = 32)
  private String etermUsername;

  /**
   * 出票时限
   */
  @Temporal(TemporalType.TIMESTAMP)
  @Column(name="tktl_time")
  private Date dzTime;

  /**
   * 出票状态
   * 0-未出票
   * 1-已出票
   */
  @Column(name = "dz_status")
  private Integer dzStatus = 0;

  /**
   * 出票日期
   * 从t233中找到对应的编码，并将他的出票日期写入进来
   */
  @Temporal(TemporalType.DATE)
  @Column(name = "etdz_date")
  private Date etdzDate;

  /**
   * 出票的office
   */
  @Column(name = "etdz_office", length = 6)
  private String etdzOffice;

  /**
   * 0 - 此编码正常状态
   * 1 - 此编码已取消
   */
  @Column(name="xe_status", length = 1)
  private Integer xeStatus = 0;

  /**
   * 航段状态
   * --用于显示PNR中需要提醒业务员注意的航段，比如HX,NO等航段
   */
  @Column(name = "seg_status", length = 10)
  private String segStatus;

  /**
   * 编码的处理状态
   * 0-不需要处理
   * 1-需要处理，取出pnrDetail，重新分析出票时限
   * 2-需要处理，取出pnrDetail, 重新分析pnrNo
   */
  private int status;


  @Transient
  private List<PnrFlight> flights;

  @Transient
  private List<PnrPassenger> passengers;

  @Transient
  private List<PnrTicket> tickets;

  /**
   * 公布运价
   */
  private int price;

  /**
   * 实际销售运价
   */
  private int parvalue;

  /**
   * 税总额
   */
  private int tax;

  @Transient
  private Double commRate;

  /**
   * 公布运价
   */
  @Column(name = "price_chd")
  private Integer chdPrice;

  /**
   * 实际销售运价
   */
  @Column(name = "parvalue_chd")
  private Integer chdParvalue;

  /**
   * 税总额
   */
  @Column(name = "tax_chd")
  private Integer chdTax;

  @Transient
  private Double chdCommRate;

  /**
   * 公布运价
   */
  @Column(name = "price_inf")
  private Integer infPrice;

  /**
   * 实际销售运价
   */
  @Column(name = "parvalue_inf")
  private Integer infParvalue;

  /**
   * 税总额
   */
  @Column(name = "tax_inf")
  private Integer infTax;

  @Transient
  private Double infCommRate;

  @Column(name = "seg_count")
  private int segCount;

  /**
   * passenger count
   */
  @Column(name = "psg_count")
  private int psgCount;

  @Column(name = "ticket_count")
  private int ticketCount;

  @Column(name = "adult_count")
  private Integer adultCount;

  @Column(name = "child_count")
  private Integer childCount;

  @Column(name = "infant_count")
  private Integer infantCount;


  /**
   * pnr中包含的ctcm数量
   */
  @Column(name = "ctcm_count")
  private Integer ctcmCount;

  @Column(name = "ctct_count")
  private Integer ctctCount;

  @Lob
  @Basic(fetch = FetchType.LAZY)
  @Column(name = "pnr_detail")
  private String pnrDetail;

  @Column(length = 2000)
  private String remark;

  /**
   * PNR的清Q日期
   */
  @Temporal(TemporalType.DATE)
  @Column(name = "issue_date", insertable = false)
  private Date issueDate;

  /**
   * 0/null - 未监控
   * 1 - 监控中, 检查NO/HX状态提醒
   * 2 - 追位，编码中的位子被NO，或HN，则查航班，并定位
   */
  private Integer monitoring = 0;


  /**
   * pnr状态是否已检查
   * 以下三个状态主要针对于状态为HX NO状态的PNR的处理
   */
  @Column(name = "check_done", length = 1)
  private String checkDone;

  /**
   * pnr状态检查时间
   */
  @Temporal(TemporalType.TIMESTAMP)
  @Column(name = "check_time")
  private Date checkTime;

  /**
   * pnr状态检查用户名
   */
  @Column(length = 20)
  private String checker;

  /**
   * 该记录保存到数据库的时间, 创建时间
   */
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  @Temporal(TemporalType.TIMESTAMP)
  @Column(name = "create_time", insertable = false, updatable = false)
  private Date createTime;

  /**
   * 最后更新时间
   */
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
  @Temporal(TemporalType.TIMESTAMP)
  @Column(insertable = false)
  private Date lastUpdate;

  /**
   * 冗余字段,保存最大的航班起飞日期
   */
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  @Temporal(TemporalType.DATE)
  @Column(name = "max_departure_date")
  private Date maxDepartureDate;

  /**
   * 冗余字段,保存最小的航班起飞日期
   */
  @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
  @Temporal(TemporalType.DATE)
  @Column(name = "min_departure_date")
  private Date minDepartureDate;


  @Column(name = "link_phone", length = 20)
  private String linkphone;

  /**
   * 预订office
   */
  @Column(name = "sd_office", length = 6)
  private String bookOfficeNo;

  /**
   * 授权office
   */
  @Transient
  private String authOfficeNo;

  /**
   * 精简的编码内容
   */
  @Transient
  private String compactPnrDetail;

  /**
   * RT结果的状态
   * 1 - 有效
   * 0 - 无效
   */
  @Transient
  private int rtResultStatus;

  /**
   * 出票时限
   */
  @Transient
  private String tktl;

  @Transient
  private String tktlDate;

  @Transient
  private String tktlTime;

  /**
   * @return the id
   */
  public int getId() {
    return id;
  }

  /**
   * @param id the id to set
   */
  public void setId(int id) {
    this.id = id;
  }

  /**
   * @return the dzTime
   */
  public Date getDzTime() {
    return dzTime;
  }

  /**
   * @param dzTime the dzTime to set
   */
  public void setDzTime(Date dzTime) {
    this.dzTime = dzTime;
  }

  /**
   * @return the price
   */
  public int getPrice() {
    return price;
  }

  /**
   * @param price the price to set
   */
  public void setPrice(int price) {
    this.price = price;
  }

  /**
   * @return the tax
   */
  public int getTax() {
    return tax;
  }

  /**
   * @param tax the tax to set
   */
  public void setTax(int tax) {
    this.tax = tax;
  }

  /**
   * @return the segCount
   */
  public int getSegCount() {
    return segCount;
  }

  /**
   * @param segCount the segCount to set
   */
  public void setSegCount(int segCount) {
    this.segCount = segCount;
  }

  /**
   * @return the psgCount
   */
  public int getPsgCount() {
    return psgCount;
  }

  /**
   * @param psgCount the psgCount to set
   */
  public void setPsgCount(int psgCount) {
    this.psgCount = psgCount;
  }

  /**
   * @return the pnrDetail
   */
  public String getPnrDetail() {
    return pnrDetail == null ? "" : pnrDetail;
  }

  /**
   * @param pnrDetail the pnrDetail to set
   */
  public void setPnrDetail(String pnrDetail) {
    this.pnrDetail = pnrDetail;
  }


  /**
   * @return the pnrNo
   */
  public String getPnrNo() {
    return this.pnrNo == null ? "" : this.pnrNo.trim();
  }

  /**
   * @param pnrNo the pnrNo to set
   */
  public void setPnrNo(String pnrNo) {
    if (pnrNo != null) {
      pnrNo = pnrNo.trim();
    }
    this.pnrNo = pnrNo;
  }

  /**
   * @return the flights
   */
  public List<PnrFlight> getFlights() {
    if (flights == null) {
      flights = new ArrayList<>();
    }
    return flights;
  }

  /**
   * @param flights the flights to set
   */
  public void setFlights(List<PnrFlight> flights) {
    this.flights = flights;
  }

  /**
   * @return the passengers
   */
  public List<PnrPassenger> getPassengers() {
    if (this.passengers == null) {
      this.passengers = new ArrayList<>();
    }
    return passengers;
  }

  /**
   * @param passengers the passengers to set
   */
  public void setPassengers(List<PnrPassenger> passengers) {
    this.passengers = passengers;
  }

  public List<PnrTicket> getTickets() {
    if (this.tickets == null) {
      this.tickets = new ArrayList<>();
    }
    return tickets;
  }

  public void setTickets(List<PnrTicket> tickets) {
    this.tickets = tickets;
  }

  public int getTicketCount() {
    return this.ticketCount;
  }

  public void setTicketCount(int ticketCount) {
    this.ticketCount = ticketCount;
  }


  public Date getIssueDate() {
    return issueDate;
  }

  public void setIssueDate(Date issueDate) {
    this.issueDate = issueDate;
  }

  /**
   * @return the remark
   */
  public String getRemark() {
    return remark;
  }

  /**
   * @param remark the remark to set
   */
  public void setRemark(String remark) {
    this.remark = remark;
  }

  /**
   * @return the customer
   */
  public Integer getCustomer() {
    return customerId;
  }

  /**
   * @param customer the customer to set
   */
  public void setCustomer(Integer customer) {
    this.customerId = customer;
  }

  /**
   * @return the enterpriseId
   */
  public int getEnterpriseId() {
    return enterpriseId;
  }

  /**
   * @param enterpriseId the enterpriseId to set
   */
  public void setEnterpriseId(int enterpriseId) {
    this.enterpriseId = enterpriseId;
  }

  public Integer getDzStatus() {

    return dzStatus;
  }

  public void setDzStatus(Integer dzStatus) {
    this.dzStatus = dzStatus;
  }

  public String getSegStatus() {
    return segStatus;
  }

  public void setSegStatus(String segStatus) {
    this.segStatus = segStatus;
  }

  public String getCheckDone() {
    return checkDone;
  }

  public void setCheckDone(String checkDone) {
    this.checkDone = checkDone;
  }

  public Date getCheckTime() {
    return checkTime;
  }

  public void setCheckTime(Date checkTime) {
    this.checkTime = checkTime;
  }

  public String getChecker() {
    return checker;
  }

  public void setChecker(String checker) {
    this.checker = checker;
  }

  public Date getLastUpdate() {
    return lastUpdate;
  }

  public void setLastUpdate(Date lastUpdate) {
    this.lastUpdate = lastUpdate;
  }

  public String getEtermUsername() {
    if (this.etermUsername == null) {
      return "";
    } else {
      return etermUsername;
    }
  }

  public void setEtermUsername(String etermUsername) {
    this.etermUsername = etermUsername;
  }



  public Date getEtdzDate() {
    return etdzDate;
  }

  public void setEtdzDate(Date etdzDate) {
    this.etdzDate = etdzDate;
  }

  public String getEtdzOffice() {
    return etdzOffice;
  }

  public void setEtdzOffice(String etdzOffice) {
    this.etdzOffice = etdzOffice;
  }

  public Integer getXeStatus() {
    if (this.xeStatus == null) {
      this.xeStatus = 0;
    }
    return xeStatus;
  }

  public void setXeStatus(Integer xeStatus) {
    this.xeStatus = xeStatus;
  }

  public int getIntXeStatus() {
    if (this.xeStatus == null) {
      return 0;
    } else {
      return this.xeStatus;
    }
  }

  public int getIntDzStatus() {
    if (this.dzStatus == null) {
      return 0;
    } else {
      return dzStatus;
    }
  }

  public Date getMinDepartureDate() {
    if (minDepartureDate == null && this.flights != null && this.flights.size() > 0) {
      try {
        minDepartureDate = DateUtil.convertToDate(flights.get(0).getFlight().getDepartureDate(), "yyyy-MM-dd");
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return minDepartureDate;
  }

  public void setMinDepartureDate(Date minDepartureDate) {
    this.minDepartureDate = minDepartureDate;
  }

  public Date getMaxDepartureDate() {
    if (maxDepartureDate == null && this.flights != null && this.flights.size() > 0) {
      int i = flights.size() - 1;
      try {
        maxDepartureDate = DateUtil.convertToDate(flights.get(i).getFlight().getDepartureDate(), "yyyy-MM-dd");
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return maxDepartureDate;
  }

  public void setMaxDepartureDate(Date maxDepartureDate) {
    this.maxDepartureDate = maxDepartureDate;
  }

  public int getStatus() {
    return status;
  }

  public void setStatus(int status) {
    this.status = status;
  }

  public String getDport() {
    return dport;
  }

  public void setDport(String departurePort) {
    this.dport = departurePort;
  }

  public String getAport() {
    return aport;
  }

  public void setAport(String arrivalPort) {
    this.aport = arrivalPort;
  }

  public String getFlightNo() {
    return flightNo;
  }

  public void setFlightNo(String flightNo) {
    this.flightNo = flightNo;
  }

  public Date getDdate() {
    return ddate;
  }

  public void setDdate(Date departureDate) {
    this.ddate = departureDate;
  }

  public String getSubclass() {
    return subclass;
  }

  public void setSubclass(String subClass) {
    this.subclass = subClass;
  }

  public String getDtime() {
    return dtime;
  }

  public void setDtime(String departureTime) {
    this.dtime = departureTime;
  }

  public Date getCreateTime() {
    return createTime;
  }

  public void setCreateTime(Date createTime) {
    this.createTime = createTime;
  }

  public String getCarrier() {
    if (flightNo == null) {
      return "";
    } else {
      return flightNo.substring(0, 2);
    }

  }

  public String getLinkphone() {
    if (this.linkphone == null) {
      return "";
    } else {
      return linkphone.trim();
    }
  }

  public void setLinkphone(String linkphone) {
    if (linkphone == null) {
      linkphone = "";
    } else if (linkphone.trim().length() > 20) {
      linkphone = linkphone.trim().substring(0, 20);
    }
    this.linkphone = linkphone;
  }

  public String getBookOfficeNo() {
    if (bookOfficeNo == null) {
      return "";
    } else {
      return bookOfficeNo;
    }
  }

  public String getAuthOfficeNo() {
    if (authOfficeNo == null) {
      return "";
    } else {
      return authOfficeNo;
    }
  }

  public void setAuthOfficeNo(String authOfficeNo) {
    this.authOfficeNo = authOfficeNo;
  }

  public String getCompactPnrDetail() {
    return compactPnrDetail;
  }

  public void setCompactPnrDetail(String compactPnrDetail) {
    this.compactPnrDetail = compactPnrDetail;
  }

  public String getBigPnrNo() {
    return this.bigPnrNo == null ? "" : bigPnrNo;
  }

  public void setBigPnrNo(String bigPnrNo) {
    if (bigPnrNo != null && bigPnrNo.trim().length() > 7) {
      this.bigPnrNo = bigPnrNo.trim().substring(0, 7);
    } else {
      this.bigPnrNo = bigPnrNo;
    }
  }

  public int getCtcmCount() {
    return ctcmCount == null ? 0 : ctcmCount;
  }

  public void setCtcmCount(Integer ctcmCount) {
    this.ctcmCount = ctcmCount;
  }

  /**
   * 检查OFFICE NO的格式
   *
   * @param officeNo
   * @return
   */
  public static boolean testOfficeNoFormat(final String officeNo) {
    String regEx = "[A-Z]{3}[0-9]{3}";
    return compile(regEx).matcher(officeNo).find();
  }

  public int getRtResultStatus() {
    return rtResultStatus;
  }

  public void setRtResultStatus(int rtResultStatus) {
    this.rtResultStatus = rtResultStatus;
  }

  public int getParvalue() {
    return parvalue;
  }

  public void setParvalue(int parvalue) {
    this.parvalue = parvalue;
  }

  public String getTktl() {
    return tktl;
  }

  public void setTktl(String tktl) {
    this.tktl = tktl;
  }

  public String getTktlTime() {
    return tktlTime;
  }

  public void setTktlTime(String tktlTime) {
    this.tktlTime = tktlTime;
  }

  public String getTktlDate() {
    return tktlDate;
  }

  public void setTktlDate(String tktlDate) {
    this.tktlDate = tktlDate;
  }

  public Integer getChdPrice() {
    return chdPrice == null ? 0 : chdPrice;
  }

  public void setChdPrice(Integer chdPrice) {
    this.chdPrice = chdPrice;
  }

  public Integer getChdParvalue() {
    return chdParvalue == null ? 0 : chdParvalue;
  }

  public void setChdParvalue(Integer chdParvalue) {
    this.chdParvalue = chdParvalue;
  }

  public Integer getChdTax() {
    return chdTax == null ? 0 : chdTax;
  }

  public void setChdTax(Integer chdTax) {
    this.chdTax = chdTax;
  }

  public int getAdultCount() {
    return adultCount == null ? 0 : adultCount;
  }

  public void setAdultCount(Integer adultCount) {
    this.adultCount = adultCount;
  }

  public Integer getChildCount() {
    return childCount == null ? 0 : childCount;
  }

  public void setChildCount(Integer childCount) {
    this.childCount = childCount;
  }

  public Double getCommRate() {
    return commRate == null ? 0 : commRate;
  }

  public void setCommRate(Double commRate) {
    this.commRate = commRate;
  }

  public Double getChdCommRate() {
    return chdCommRate == null ? 0 : chdCommRate;
  }

  public void setChdCommRate(Double chdCommRate) {
    this.chdCommRate = chdCommRate;
  }

  public Integer getInfPrice() {
    return infPrice == null ? 0 : infPrice;
  }

  public void setInfPrice(Integer infPrice) {
    this.infPrice = infPrice;
  }

  public Integer getInfParvalue() {
    return infParvalue == null ? 0 : infParvalue;
  }

  public void setInfParvalue(Integer infParvalue) {
    this.infParvalue = infParvalue;
  }

  public Integer getInfTax() {
    return infTax == null ? 0 : infTax;
  }

  public void setInfTax(Integer infTax) {
    this.infTax = infTax;
  }

  public Double getInfCommRate() {
    return infCommRate == null ? 0 : infCommRate;
  }

  public void setInfCommRate(Double infCommRate) {
    this.infCommRate = infCommRate;
  }

  public int getInfantCount() {
    return infantCount == null ? 0 : infantCount;
  }

  public void setInfantCount(Integer infantCount) {
    this.infantCount = infantCount;
  }

  public Integer getMonitoring() {
    return monitoring;
  }

  public void setMonitoring(Integer monitoring) {
    this.monitoring = monitoring;
  }

  public void setBookOfficeNo(String bookOfficeNo) {
    this.bookOfficeNo = bookOfficeNo;
  }

  public Integer getCtctCount() {
    return ctctCount;
  }

  public void setCtctCount(Integer ctctCount) {
    this.ctctCount = ctctCount;
  }
}
